#include <stdef.h>
#include <stdint.h>
#include <stdlib.h>

#include "misc.h"
#include "debug.h"
#include "strategy.h"

/**
 * @brief map对象的比较操作回调函数。
 */
void strategy_map_cmp_func__( void * a , void * b , void * rst )
{
	struct stKeyWrap * a__ = ( struct stKeyWrap *)a , * b__ = ( struct stKeyWrap *)b;
	if( a__->p_obj ){
		*(bool*)rst = a__->p_obj->cmp_func( a__->p_key , b->p_key );
	}else if( b__->p_obj ){
		*(bool*)rst = b__->p_obj->cmp_func( a__->p_key , b->p_key );
	}else{
		ERROR_MSG( "找不到数据对象" );
		*(bool*)rst = false;
	}
}
/**
 * @brief 释放对象
 */
void release_strategy__( strategy_t * ctx )
{
	if( ctx->p_map ){
		map_iterator_it b = map_begin( ctx->p_map ) , e = map_end( ctx->p_map );
		// 释放所有的键关联的内存
		for( ;iterator_equal( b , e ) == false; b = iterator_next( b ) ){
			pair_t * p = iterator_get_pointer( b );
			if( p ){
				struct stKeyWrap * w = *( struct stKeyWrap **)pair_first( p );
				if( w ){
					// 执行释放操作
					if( w->p_obj && w->p_obj->key_free_func ){
						w->p_obj->key_free_func(ctx->p_user , w->p_key );
					}
					
					free( w );
				}
			}
		}
		map_destroy( ctx->p_map );
	}

	free( ctx );
}

strategy_t * newStrategy( strategyKeyCmpFunc funccmp , strategyKeyFree funcfree , void * user )
{
	strategy_t * ret = ( strategy_t *)malloc( sizeof( strategy_t ) );
	if( !ret ){
		ERRROR_MSG( "内存分配失败" );
		printCallstack();
		return ret;
	}
	ret->cmp_func = funccmp;
	ret->key_free_func = funcfree;
	ret->p_user = user;
	//                   struct stKeyWrap , strategyCallFunc 
	ret->p_map = create_map( void * , void * );
	if( !ret->p_map ){
		ERROR_MSG( "内存分配失败" );
		relase_strategy__( ret );
	}
       
	map_init_ex( ret->p_map , ret->cmp_func );

	return ret;
}

void releaseStrategy( strategy_t * ctx )
{
	if( !ctx ){
		return;
	}

	release_strategy__( ctx );
}

bool strategyAdd( strategy_t * ctx , void * key , strategyCallFunc * func )
{
	bool ret = true;
	struct stKeyWrap * key = ( struct stKeyWrap *)calloc( sizeof( struct stKeyWrap ) );
	if( key ){
		key->p_obj = ctx;
		key->p_key = key;

		pair_t * p = create_pair();
		if( p ){
			pair_init_elem( p , key , func );
			map_insert( p );

			pair_destroy( p );
		}
	}
	return ret;
}
     

bool strategyErase( strategy_t * ctx , void * key )
{
	if( !ctx || !key ){
		ERROR_MSG( "测试模式模块对象指针无效，或者key无效" );
		return false;
	}
	struct stKeyWrap w = { .p_key = key, .p_obj = ctx };
	
	map_iterator_t b = map_find( ctx->p_map , &w ) , e = map_end( ctx->p_map );
	if( iterator_equal( b, e ) == false ){
		pair_t * p = iterator_get_pointer( b );
		if( p ){
			struct stKeyWrap * w = *(struct stKeyWrap**)pair_first( p );
			if( ctx->key_free_func && w ){
				ctx->key_free_func( w );
			}
		}

		map_erase_pos( ctx->p_map , b );
		return true;
	}

	return false;
}

void * strategyCall( strategy_t * ctx , void * key , void * params )
{
	struct stKeyWrap w = { .p_key = key, .p_obj = ctx };
	map_iterator_t b = map_find( ctx->p_map , &w ) , e = map_end( ctx->p_map );
	if( iterator_equal( b, e ) == false ){
		pair_t * p = iterator_get_pointer( b );
		if( p ){
			strategyCallFunc func = (strategyCallFunc)pair_second( p );
			if( func ){
				void * rst = func( ctx->p_user , params );
				return rst;
			}else{
				ERROR_MSG( "目标方法无效" );
			}
		}else{
			ERROR_MSG( "内部错误，pair_t 对象无效" );
		}
	}else{
		ERROR_MSG( "找不到目标方法" );
	}
	return NULL;
}
